#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
企业公告智能监控大屏 - FastAPI后端
提供所有大屏数据接口
"""

from fastapi import FastAPI, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
import sqlite3
import json
from datetime import datetime, timedelta
from typing import Optional, List, Dict, Any
import os
from pathlib import Path
import config

# 创建FastAPI应用
app = FastAPI(title="企业公告智能监控大屏API", version="1.0.0")

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 数据库配置
DATABASE_PATH = "announcements.db"

def get_db_connection():
    """获取数据库连接"""
    conn = sqlite3.connect(DATABASE_PATH)
    conn.row_factory = sqlite3.Row
    return conn

def format_date(date_str: str) -> str:
    """格式化日期字符串"""
    if not date_str:
        return ""
    try:
        # 尝试解析不同格式的日期
        if 'T' in date_str:
            dt = datetime.fromisoformat(date_str.replace('Z', '+00:00'))
        else:
            dt = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
        return dt.strftime('%Y-%m-%d %H:%M:%S')
    except:
        return date_str

# ===== 第一屏：总览仪表板 API =====

@app.get("/api/overview/kpis")
async def get_overview_kpis():
    """获取总览KPI数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 总公告数
        cursor.execute("SELECT COUNT(*) as total FROM announcements")
        total_announcements = cursor.fetchone()['total']
        
        # 已分析公告数
        cursor.execute("SELECT COUNT(*) as analyzed FROM announcement_insights")
        analyzed_announcements = cursor.fetchone()['analyzed']
        
        # 今日新增公告
        today = datetime.now().strftime('%Y-%m-%d')
        cursor.execute("SELECT COUNT(*) as today_count FROM announcements WHERE DATE(publishTime) = ?", (today,))
        today_announcements = cursor.fetchone()['today_count']
        
        # 高风险公告数（严重利空 + 毁灭性利空）
        cursor.execute("""
            SELECT COUNT(*) as high_risk 
            FROM announcement_insights 
            WHERE negative_level IN ('严重利空', '毁灭性利空')
        """)
        high_risk_count = cursor.fetchone()['high_risk']
        
        # 利好公告数
        cursor.execute("""
            SELECT COUNT(*) as positive_count 
            FROM announcement_insights 
            WHERE positive_level IN ('轻微利好', '一般利好', '重大利好', '变革性利好')
        """)
        positive_count = cursor.fetchone()['positive_count']
        
        # 利空公告数
        cursor.execute("""
            SELECT COUNT(*) as negative_count 
            FROM announcement_insights 
            WHERE negative_level IN ('轻微利空', '一般利空', '严重利空', '毁灭性利空')
        """)
        negative_count = cursor.fetchone()['negative_count']
        
        return {
            "total_announcements": total_announcements,
            "analyzed_announcements": analyzed_announcements,
            "today_announcements": today_announcements,
            "high_risk_count": high_risk_count,
            "positive_count": positive_count,
            "negative_count": negative_count
        }
    finally:
        conn.close()

@app.get("/api/overview/trends")
async def get_overview_trends(days: int = Query(7, description="天数")):
    """获取公告发布趋势数据（堆叠图）"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 按天统计公告数量，包括利好、利空、中性分类
        cursor.execute("""
            SELECT 
                DATE(a.publishTime) as date,
                COUNT(*) as total,
                SUM(CASE WHEN ai.positive_level IN ('轻微利好', '一般利好', '重大利好', '变革性利好') THEN 1 ELSE 0 END) as positive,
                SUM(CASE WHEN ai.negative_level IN ('轻微利空', '一般利空', '严重利空', '毁灭性利空') THEN 1 ELSE 0 END) as negative,
                SUM(CASE WHEN (ai.positive_level = '无利好信息' OR ai.positive_level IS NULL) AND (ai.negative_level = '无利空信息' OR ai.negative_level IS NULL) THEN 1 ELSE 0 END) as neutral
            FROM announcements a
            LEFT JOIN announcement_insights ai ON a.id = ai.announcement_id
            WHERE DATE(a.publishTime) >= DATE('now', '-{} days')
            GROUP BY DATE(a.publishTime)
            ORDER BY DATE(a.publishTime) ASC
        """.format(days))
        
        results = cursor.fetchall()
        
        # 确保数据按时间顺序排列
        trend_data = []
        for row in results:
            trend_data.append({
                "date": row['date'],
                "total": row['total'],
                "positive": row['positive'],
                "negative": row['negative'],
                "neutral": row['neutral']
            })
        
        return trend_data
    finally:
        conn.close()

@app.get("/api/overview/latest-announcements")
async def get_latest_announcements(limit: int = Query(20, description="数量限制")):
    """获取最新公告列表"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                a.secCode,
                a.secName,
                a.title,
                a.publishTime,
                ai.positive_level,
                ai.negative_level,
                ai.insight_summary
            FROM announcements a
            LEFT JOIN announcement_insights ai ON a.id = ai.announcement_id
            ORDER BY a.publishTime DESC
            LIMIT ?
        """, (limit,))
        
        results = cursor.fetchall()
        
        announcements = []
        for row in results:
            announcements.append({
                "secCode": row['secCode'],
                "secName": row['secName'],
                "title": row['title'],
                "publishTime": row['publishTime'],
                "positive_level": row['positive_level'],
                "negative_level": row['negative_level'],
                "insight_summary": row['insight_summary']
            })
        
        return announcements
    finally:
        conn.close()

@app.get("/api/overview/risk-alerts")
async def get_risk_alerts(limit: int = Query(10, description="数量限制")):
    """获取风险预警数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                ai.secCode,
                ai.secName,
                ai.title,
                ai.publishTime,
                ai.negative_level,
                ai.negative_reason,
                ai.negative_keywords
            FROM announcement_insights ai
            WHERE ai.negative_level IN ('严重利空', '毁灭性利空')
            ORDER BY ai.publishTime DESC
            LIMIT ?
        """, (limit,))
        
        results = cursor.fetchall()
        
        alerts = []
        for row in results:
            negative_keywords = []
            if row['negative_keywords']:
                try:
                    negative_keywords = json.loads(row['negative_keywords'])
                except:
                    pass
            
            alerts.append({
                "secCode": row['secCode'],
                "secName": row['secName'],
                "title": row['title'],
                "publishTime": row['publishTime'],
                "negative_level": row['negative_level'],
                "negative_reason": row['negative_reason'],
                "negative_keywords": negative_keywords
            })
        
        return alerts
    finally:
        conn.close()

@app.get("/api/overview/company-activity")
async def get_company_activity(limit: int = Query(10, description="数量限制")):
    """获取公司活跃度数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                secCode,
                secName,
                COUNT(*) as announcement_count
            FROM announcements
            WHERE DATE(publishTime) >= DATE('now', '-30 days')
            GROUP BY secCode, secName
            ORDER BY announcement_count DESC
            LIMIT ?
        """, (limit,))
        
        results = cursor.fetchall()
        
        activity = []
        for row in results:
            activity.append({
                "secCode": row['secCode'],
                "secName": row['secName'],
                "count": row['announcement_count']
            })
        
        return activity
    finally:
        conn.close()

@app.get("/api/overview/keywords")
async def get_keywords(keyword_type: str = Query("positive", description="关键词类型：positive/negative")):
    """获取热门关键词数据（带详细信息支持弹窗）"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        column_name = "positive_keywords" if keyword_type == "positive" else "negative_keywords"
        
        cursor.execute(f"""
            SELECT 
                ai.{column_name} as keywords,
                ai.secCode,
                ai.secName,
                ai.title,
                ai.publishTime,
                ai.positive_reason,
                ai.negative_reason
            FROM announcement_insights ai
            WHERE ai.{column_name} IS NOT NULL AND ai.{column_name} != '[]'
        """)
        
        results = cursor.fetchall()
        
        # 统计关键词频次并收集详细信息
        keyword_stats = {}
        for row in results:
            try:
                keywords = json.loads(row['keywords'])
                for keyword in keywords:
                    if keyword not in keyword_stats:
                        keyword_stats[keyword] = {
                            "count": 0,
                            "details": []
                        }
                    keyword_stats[keyword]["count"] += 1
                    keyword_stats[keyword]["details"].append({
                        "secCode": row['secCode'],
                        "secName": row['secName'],
                        "title": row['title'],
                        "publishTime": row['publishTime'],
                        "reason": row['positive_reason'] if keyword_type == "positive" else row['negative_reason']
                    })
            except:
                continue
        
        # 按频次排序并返回前20个
        sorted_keywords = sorted(keyword_stats.items(), key=lambda x: x[1]["count"], reverse=True)[:20]
        
        result = []
        for keyword, data in sorted_keywords:
            result.append({
                "keyword": keyword,
                "count": data["count"],
                "details": data["details"]
            })
        
        return result
    finally:
        conn.close()

# ===== 第二屏：公告来源分析 API =====

@app.get("/api/source/daily-stats")
async def get_source_daily_stats(days: int = Query(30, description="天数")):
    """获取每日公告统计数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                DATE(publishTime) as date,
                COUNT(*) as count
            FROM announcements
            WHERE DATE(publishTime) >= DATE('now', '-{} days')
            GROUP BY DATE(publishTime)
            ORDER BY DATE(publishTime) ASC
        """.format(days))
        
        results = cursor.fetchall()
        
        daily_stats = []
        for row in results:
            daily_stats.append({
                "date": row['date'],
                "count": row['count']
            })
        
        return daily_stats
    finally:
        conn.close()

@app.get("/api/source/exchange-stats")
async def get_exchange_stats():
    """获取交易所统计数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 根据股票代码判断交易所
        cursor.execute("""
            SELECT 
                CASE 
                    WHEN secCode LIKE '0%' OR secCode LIKE '3%' THEN '深交所'
                    WHEN secCode LIKE '6%' THEN '上交所'
                    WHEN secCode LIKE '8%' OR secCode LIKE '4%' THEN '北交所'
                    ELSE '其他'
                END as exchange,
                COUNT(*) as count
            FROM announcements
            WHERE DATE(publishTime) >= DATE('now', '-30 days')
            GROUP BY exchange
            ORDER BY count DESC
        """)
        
        results = cursor.fetchall()
        
        exchange_stats = []
        for row in results:
            exchange_stats.append({
                "exchange": row['exchange'],
                "count": row['count']
            })
        
        return exchange_stats
    finally:
        conn.close()

@app.get("/api/source/hourly-distribution")
async def get_hourly_distribution():
    """获取24小时发布分布数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                CAST(strftime('%H', publishTime) AS INTEGER) as hour,
                COUNT(*) as count
            FROM announcements
            WHERE DATE(publishTime) >= DATE('now', '-7 days')
            GROUP BY hour
            ORDER BY hour
        """)
        
        results = cursor.fetchall()
        
        hourly_data = []
        for row in results:
            hourly_data.append({
                "hour": row['hour'],
                "count": row['count']
            })
        
        return hourly_data
    finally:
        conn.close()

# ===== 第三屏：情感分析报告 API =====

@app.get("/api/sentiment/analysis-stats")
async def get_sentiment_analysis_stats():
    """获取情感分析统计数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 利好等级分布
        cursor.execute("""
            SELECT 
                positive_level,
                COUNT(*) as count
            FROM announcement_insights
            WHERE positive_level IS NOT NULL
            GROUP BY positive_level
            ORDER BY count DESC
        """)
        positive_stats = cursor.fetchall()
        
        # 利空等级分布
        cursor.execute("""
            SELECT 
                negative_level,
                COUNT(*) as count
            FROM announcement_insights
            WHERE negative_level IS NOT NULL
            GROUP BY negative_level
            ORDER BY count DESC
        """)
        negative_stats = cursor.fetchall()
        
        return {
            "positive_distribution": [{"level": row['positive_level'], "count": row['count']} for row in positive_stats],
            "negative_distribution": [{"level": row['negative_level'], "count": row['count']} for row in negative_stats]
        }
    finally:
        conn.close()

@app.get("/api/sentiment/intensity-distribution")
async def get_sentiment_intensity_distribution():
    """获取情感强度分布数据（带详细信息）"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 利好强度分布（带详细信息）
        cursor.execute("""
            SELECT 
                positive_level,
                secCode,
                secName,
                title,
                publishTime,
                positive_reason
            FROM announcement_insights
            WHERE positive_level IN ('轻微利好', '一般利好', '重大利好', '变革性利好')
            ORDER BY publishTime DESC
        """)
        positive_results = cursor.fetchall()
        
        # 利空强度分布（带详细信息）
        cursor.execute("""
            SELECT 
                negative_level,
                secCode,
                secName,
                title,
                publishTime,
                negative_reason
            FROM announcement_insights
            WHERE negative_level IN ('轻微利空', '一般利空', '严重利空', '毁灭性利空')
            ORDER BY publishTime DESC
        """)
        negative_results = cursor.fetchall()
        
        # 组织数据
        positive_data = {}
        for row in positive_results:
            level = row['positive_level']
            if level not in positive_data:
                positive_data[level] = {
                    "count": 0,
                    "details": []
                }
            positive_data[level]["count"] += 1
            positive_data[level]["details"].append({
                "secCode": row['secCode'],
                "secName": row['secName'],
                "title": row['title'],
                "publishTime": row['publishTime'],
                "reason": row['positive_reason']
            })
        
        negative_data = {}
        for row in negative_results:
            level = row['negative_level']
            if level not in negative_data:
                negative_data[level] = {
                    "count": 0,
                    "details": []
                }
            negative_data[level]["count"] += 1
            negative_data[level]["details"].append({
                "secCode": row['secCode'],
                "secName": row['secName'],
                "title": row['title'],
                "publishTime": row['publishTime'],
                "reason": row['negative_reason']
            })
        
        return {
            "positive_intensity": positive_data,
            "negative_intensity": negative_data
        }
    finally:
        conn.close()

# ===== 第四屏：风险监控预警 API =====

@app.get("/api/risk/high-risk-stats")
async def get_high_risk_stats():
    """获取高风险统计数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 高风险公告数量
        cursor.execute("""
            SELECT COUNT(*) as high_risk_count
            FROM announcement_insights
            WHERE negative_level IN ('严重利空', '毁灭性利空')
        """)
        high_risk_count = cursor.fetchone()['high_risk_count']
        
        # 涉及高风险的公司数量
        cursor.execute("""
            SELECT COUNT(DISTINCT secCode) as high_risk_companies
            FROM announcement_insights
            WHERE negative_level IN ('严重利空', '毁灭性利空')
        """)
        high_risk_companies = cursor.fetchone()['high_risk_companies']
        
        # 今日新增高风险
        today = datetime.now().strftime('%Y-%m-%d')
        cursor.execute("""
            SELECT COUNT(*) as today_high_risk
            FROM announcement_insights
            WHERE negative_level IN ('严重利空', '毁灭性利空')
            AND DATE(publishTime) = ?
        """, (today,))
        today_high_risk = cursor.fetchone()['today_high_risk']
        
        return {
            "high_risk_count": high_risk_count,
            "high_risk_companies": high_risk_companies,
            "today_high_risk": today_high_risk
        }
    finally:
        conn.close()

@app.get("/api/risk/trend")
async def get_risk_trend(days: int = Query(30, description="天数")):
    """获取风险趋势数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                DATE(publishTime) as date,
                SUM(CASE WHEN negative_level = '严重利空' THEN 1 ELSE 0 END) as severe,
                SUM(CASE WHEN negative_level = '毁灭性利空' THEN 1 ELSE 0 END) as destructive
            FROM announcement_insights
            WHERE DATE(publishTime) >= DATE('now', '-{} days')
            AND negative_level IN ('严重利空', '毁灭性利空')
            GROUP BY DATE(publishTime)
            ORDER BY DATE(publishTime) ASC
        """.format(days))
        
        results = cursor.fetchall()
        
        trend_data = []
        for row in results:
            trend_data.append({
                "date": row['date'],
                "severe": row['severe'],
                "destructive": row['destructive']
            })
        
        return trend_data
    finally:
        conn.close()

@app.get("/api/risk/companies")
async def get_risk_companies(limit: int = Query(20, description="数量限制")):
    """获取风险公司列表（带详细信息）"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                secCode,
                secName,
                negative_level,
                title,
                publishTime,
                negative_reason,
                negative_keywords
            FROM announcement_insights
            WHERE negative_level IN ('严重利空', '毁灭性利空')
            ORDER BY publishTime DESC
            LIMIT ?
        """, (limit,))
        
        results = cursor.fetchall()
        
        companies = []
        for row in results:
            negative_keywords = []
            if row['negative_keywords']:
                try:
                    negative_keywords = json.loads(row['negative_keywords'])
                except:
                    pass
            
            companies.append({
                "secCode": row['secCode'],
                "secName": row['secName'],
                "negative_level": row['negative_level'],
                "title": row['title'],
                "publishTime": row['publishTime'],
                "negative_reason": row['negative_reason'],
                "negative_keywords": negative_keywords
            })
        
        return companies
    finally:
        conn.close()

# ===== 第五屏：系统运行状态 API =====

@app.get("/api/system/processing-stats")
async def get_processing_stats():
    """获取处理统计数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 总处理量
        cursor.execute("SELECT COUNT(*) as total_processed FROM announcement_insights")
        total_processed = cursor.fetchone()['total_processed']
        
        # 今日处理量
        today = datetime.now().strftime('%Y-%m-%d')
        cursor.execute("""
            SELECT COUNT(*) as today_processed 
            FROM announcement_insights 
            WHERE DATE(created_at) = ?
        """, (today,))
        today_processed = cursor.fetchone()['today_processed']
        
        # 待处理量
        cursor.execute("""
            SELECT COUNT(*) as pending
            FROM announcements a
            LEFT JOIN announcement_insights ai ON a.id = ai.announcement_id
            WHERE ai.announcement_id IS NULL
        """)
        pending_count = cursor.fetchone()['pending']
        
        return {
            "total_processed": total_processed,
            "today_processed": today_processed,
            "pending_count": pending_count
        }
    finally:
        conn.close()

@app.get("/api/system/daily-processing")
async def get_daily_processing(days: int = Query(7, description="天数")):
    """获取每日处理量数据"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        cursor.execute("""
            SELECT 
                DATE(created_at) as date,
                COUNT(*) as count
            FROM announcement_insights
            WHERE DATE(created_at) >= DATE('now', '-{} days')
            GROUP BY DATE(created_at)
            ORDER BY DATE(created_at) ASC
        """.format(days))
        
        results = cursor.fetchall()
        
        daily_data = []
        for row in results:
            daily_data.append({
                "date": row['date'],
                "count": row['count']
            })
        
        return daily_data
    finally:
        conn.close()

@app.get("/api/system/data-quality")
async def get_data_quality():
    """获取数据质量统计"""
    conn = get_db_connection()
    try:
        cursor = conn.cursor()
        
        # 有效分析数据
        cursor.execute("""
            SELECT COUNT(*) as valid_analysis
            FROM announcement_insights
            WHERE insight_summary IS NOT NULL 
            AND insight_summary != ''
            AND LENGTH(insight_summary) > 10
        """)
        valid_analysis = cursor.fetchone()['valid_analysis']
        
        # 总分析数据
        cursor.execute("SELECT COUNT(*) as total_analysis FROM announcement_insights")
        total_analysis = cursor.fetchone()['total_analysis']
        
        # 数据质量评分
        quality_score = (valid_analysis / total_analysis * 100) if total_analysis > 0 else 0
        
        return {
            "valid_analysis": valid_analysis,
            "total_analysis": total_analysis,
            "quality_score": round(quality_score, 2)
        }
    finally:
        conn.close()

@app.get("/api/system/storage-stats")
async def get_storage_stats():
    """获取存储统计数据"""
    storage_stats = {
        "database_size": "0 MB",
        "pdf_count": 0,
        "pdf_storage": "0 MB"
    }
    
    try:
        # 数据库大小
        if os.path.exists(DATABASE_PATH):
            db_size = os.path.getsize(DATABASE_PATH)
            storage_stats["database_size"] = f"{db_size / 1024 / 1024:.2f} MB"
        
        # PDF文件统计
        pdf_folder = "temp_pdfs"
        if os.path.exists(pdf_folder):
            pdf_files = [f for f in os.listdir(pdf_folder) if f.endswith('.pdf')]
            storage_stats["pdf_count"] = len(pdf_files)
            
            total_pdf_size = sum(os.path.getsize(os.path.join(pdf_folder, f)) for f in pdf_files)
            storage_stats["pdf_storage"] = f"{total_pdf_size / 1024 / 1024:.2f} MB"
    
    except Exception as e:
        print(f"获取存储统计失败: {e}")
    
    return storage_stats

# ===== 静态文件服务和主页 =====

# 挂载静态文件目录
app.mount("/static", StaticFiles(directory="static"), name="static")

@app.get("/", response_class=HTMLResponse)
async def read_root():
    """主页 - 总览大屏"""
    html_file = Path("templates/overview.html")
    if html_file.exists():
        return html_file.read_text(encoding='utf-8')
    else:
        return """
        <html>
            <body>
                <h1>企业公告智能监控大屏</h1>
                <p>请创建 templates/overview.html 文件</p>
                <ul>
                    <li><a href="/source">公告来源分析</a></li>
                    <li><a href="/sentiment">情感分析报告</a></li>
                    <li><a href="/risk">风险监控预警</a></li>
                    <li><a href="/system">系统运行状态</a></li>
                </ul>
            </body>
        </html>
        """

@app.get("/source", response_class=HTMLResponse)
async def source_dashboard():
    """公告来源分析大屏"""
    html_file = Path("templates/source.html")
    if html_file.exists():
        return html_file.read_text(encoding='utf-8')
    else:
        return "<h1>公告来源分析大屏</h1><p>请创建 templates/source.html 文件</p>"

@app.get("/sentiment", response_class=HTMLResponse)
async def sentiment_dashboard():
    """情感分析报告大屏"""
    html_file = Path("templates/sentiment.html")
    if html_file.exists():
        return html_file.read_text(encoding='utf-8')
    else:
        return "<h1>情感分析报告大屏</h1><p>请创建 templates/sentiment.html 文件</p>"

@app.get("/risk", response_class=HTMLResponse)
async def risk_dashboard():
    """风险监控预警大屏"""
    html_file = Path("templates/risk.html")
    if html_file.exists():
        return html_file.read_text(encoding='utf-8')
    else:
        return "<h1>风险监控预警大屏</h1><p>请创建 templates/risk.html 文件</p>"

@app.get("/system", response_class=HTMLResponse)
async def system_dashboard():
    """系统运行状态大屏"""
    html_file = Path("templates/system.html")
    if html_file.exists():
        return html_file.read_text(encoding='utf-8')
    else:
        return "<h1>系统运行状态大屏</h1><p>请创建 templates/system.html 文件</p>"

if __name__ == "__main__":
    import uvicorn
    
    # 创建必要的目录
    os.makedirs("templates", exist_ok=True)
    os.makedirs("static", exist_ok=True)
    
    print("企业公告智能监控大屏系统启动中...")
    print("API文档: http://localhost:8000/docs")
    print("总览大屏: http://localhost:8000/")
    
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True) 